<template>
    <div class="fp-wrap">
      <!-- 图片：单元格缩略 + 点击进入大图 -->
      <el-image
        v-if="isImage(kind) && absUrl"
        :src="absUrl"
        :preview-src-list="[absUrl]"
        :preview-teleported="true"
        :z-index="4000"
        fit="contain"
        class="fp-thumb"
      >
        <template #error><span class="fp-muted">图片加载失败</span></template>
      </el-image>
  
      <!-- PDF：单元格小预览 + 点击放大 -->
      <div v-else-if="isPdf(kind) && absUrl" class="fp-pdf" @click="openPdf" title="点击预览 PDF">
        <object :data="absUrl + '#toolbar=0&navpanes=0&view=FitH'" type="application/pdf" width="100%" height="120">
          <div class="fp-muted">PDF 预览不可用</div>
        </object>
        <div class="fp-pdf-mask">点击预览</div>
      </div>
  
      <!-- 其他：下载 -->
      <div v-else class="fp-actions">
        <el-button link type="primary" @click="doDownload">下载</el-button>
      </div>
  
      <!-- PDF 大窗预览 -->
      <el-dialog v-model="pdf.open" width="80%" top="5vh" :destroy-on-close="true" append-to-body title="PDF 预览">
        <iframe v-if="pdf.url" :src="pdf.url + '#toolbar=1&navpanes=0&scrollbar=1'" style="width:100%;height:80vh;border:none;"></iframe>
        <template #footer>
          <el-button @click="doDownload">下载</el-button>
          <el-button type="primary" @click="pdf.open=false">关 闭</el-button>
        </template>
      </el-dialog>
    </div>
  </template>
  
  <script setup>
  import { computed, reactive } from 'vue'
  import { ElMessage } from 'element-plus'
  
  const props = defineProps({
    /** 直接传整行数据 row；内部会自己解析 url/mime/ext/name */
    file: { type: Object, default: () => ({}) },
    /** （可选）你项目的 baseApi，例如 import.meta.env.VITE_APP_BASE_API */
    baseApi: { type: String, default: '' },
    /** （可选）直接传 URL 时可用 */
    url: { type: String, default: '' },
    /** （可选）显式传类型：image / application/pdf / png 等 */
    type: { type: String, default: '' },
    /** （可选）显式传文件名（用于下载） */
    name: { type: String, default: '' },
  })
  
  /** —— 工具：构造可访问 URL —— */
  function makeAbsUrl(path, baseApi = '') {
    if (!path) return ''
    if (/^(https?:)?\/\//i.test(path)) return path
    const prefix = baseApi || (typeof import.meta !== 'undefined' && import.meta.env && import.meta.env.VITE_APP_BASE_API) || (typeof process !== 'undefined' && process.env && process.env.VUE_APP_BASE_API) || ''
    if (prefix) {
      const left = String(prefix).replace(/\/+$/, '')
      const right = path.startsWith('/') ? path : '/' + path
      return left + right
    }
    return path.startsWith('/') ? path : '/' + path
  }
  
  /** —— 解析行数据 —— */
  const rawUrl = computed(() => {
    return props.url
        || props.file?.storageUrl
        || props.file?.fileUrl
        || props.file?.url
        || ''
  })
  const absUrl = computed(() => makeAbsUrl(rawUrl.value, props.baseApi))
  
  const kind = computed(() => {
    const s = (props.type || props.file?.previewType || props.file?.mimeType || props.file?.ext || '').toString().toLowerCase().trim()
    return s
  })
  
  function isImage(s) {
    if (!s) return false
    if (s === 'image') return true
    if (s.startsWith('image/')) return true
    const ext = s.includes('.') ? s.split('.').pop() : s
    return ['png','jpg','jpeg','gif','webp','bmp','svg'].includes(ext)
  }
  function isPdf(s) {
    if (!s) return false
    if (s === 'pdf') return true
    if (s === 'application/pdf') return true
    return s.endsWith('.pdf')
  }
  
  const filename = computed(() =>
    props.name || props.file?.originalName || props.file?.fileName || '文件'
  )
  
  const pdf = reactive({ open: false, url: '' })
  function openPdf() {
    if (!absUrl.value) return
    pdf.url = absUrl.value
    pdf.open = true
  }
  
  function doDownload() {
    const url = absUrl.value
    if (!url) {
      ElMessage.warning('无可下载的地址')
      return
    }
    const a = document.createElement('a')
    a.href = url
    a.download = String(filename.value)
    a.target = '_blank'
    document.body.appendChild(a)
    a.click()
    document.body.removeChild(a)
  }
  </script>
  
  <style scoped>
  .fp-wrap{ display:inline-flex; align-items:center; }
  .fp-thumb{
    width:160px; height:120px; background:#f5f7fa; border-radius:6px; overflow:hidden; display:inline-flex; align-items:center; justify-content:center;
  }
  :deep(.fp-thumb .el-image__inner){ width:100%; height:100%; object-fit:contain; }
  .fp-muted{ color:#909399; font-size:12px; }
  .fp-pdf{
    width:160px; height:120px; position:relative; border:1px solid #ebeef5; border-radius:6px; overflow:hidden; background:#fafafa; cursor:pointer;
  }
  .fp-pdf-mask{
    position:absolute; left:0; right:0; bottom:0; height:22px; line-height:22px; text-align:center; font-size:12px; color:#fff; background:rgba(0,0,0,.35);
  }
  </style>
  